package com.woniuxy.cloud.carl.marketing.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.druid.sql.visitor.functions.Now;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sun.corba.se.spi.resolver.Resolver;
import com.woniuxy.cloud.carl.marketing.client.param.AddUserCouponParam;
import com.woniuxy.cloud.carl.marketing.client.result.CouponDto;
import com.woniuxy.cloud.carl.marketing.common.StatusEnum;
import com.woniuxy.cloud.carl.marketing.infra.model.*;
import com.woniuxy.cloud.carl.marketing.infra.mapper.CouponMapper;
import com.woniuxy.cloud.carl.marketing.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.exceptions.MallException;
import com.woniuxy.result.CommonResultCodeEnum;
import com.woniuxy.result.Result;
import com.woniuxy.utils.Assert;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 优惠券记录表 服务实现类
 * </p>
 *
 * @author Lucas
 * @since 2023-07-19
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {
    @Autowired
    DeductionService deductionService;
    @Autowired
    FullDiscountCouponService fullDiscountCouponService;
    @Autowired
    ServiceCouponService serviceCouponService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private CouponSpuService couponSpuService;
    @Override
    public Result<List<CouponDto>> getCouponByUserId(Long userId) {
        List<Coupon> list = list(new QueryWrapper<Coupon>().eq("user_id",userId));
        ArrayList<CouponDto> couponDtos = new ArrayList<>();
        list.forEach(o->{
            CouponDto couponDto = BeanUtil.copyProperties(o, CouponDto.class);
            Integer typeId=o.getCouponType().intValue();
            couponDto.setCouponType(typeId==StatusEnum.DEDUCTION_FLAG.getCode()?"抵扣券":
                    typeId==StatusEnum.FULL_DISCOUNT_FLAG.getCode()?"满减券":"服务券");
            switch (o.getCouponStatus()){
                case (0):{
                    couponDto.setCouponStatus(StatusEnum.USER_COUPON_NOT_USE.getStatus());
                    break;
                }
                case (1):{
                    couponDto.setCouponStatus(StatusEnum.USER_COUPON_USED.getStatus());
                    break;
                }
                case (2):{
                    couponDto.setCouponStatus(StatusEnum.USER_COUPON_LATE.getStatus());
                    break;
                }
                default:{
                    break;
                }
            }
//            因为枚举中放的东西太多，放弃这个方法
//            StatusEnum anEnum = StatusEnum.getEnum(o.getCouponStatus());
//            if (anEnum==null) throw new MallException(CommonResultCodeEnum.ILLEGAL_STATE,"状态错误");
//            couponDto.setCouponStatus(anEnum.getStatus());
            couponDtos.add(couponDto);
        });
        return Result.success(couponDtos);
    }

    @Override
    public Result addUserCoupon(AddUserCouponParam param) {
        if (param.getCouponType()>3||param.getCouponType()<1)
            throw new MallException(CommonResultCodeEnum.ILLEGAL_STATE,"优惠券信息错误");
        RScoredSortedSet<String> coupon_count = redissonClient.getScoredSortedSet("coupon_count");
        if (coupon_count.size()!=0&&coupon_count.contains(param.getCouponId())){
            Double score = coupon_count.getScore(param.getCouponId());
            if (score<1){
                coupon_count.remove(param.getCouponId());
                throw new MallException(CommonResultCodeEnum.FAIL,"该类型优惠券已被领完");
            }
            coupon_count.add(score-1,param.getCouponId());
        }
        Coupon coupon = new Coupon();
        switch (param.getCouponType().intValue()){
            //抵扣券
            case (1):{
                Deduction deduction = deductionService.getById(param.getCouponId());
                Assert.state(deduction!=null,"优惠券信息错误");
                Assert.state(deduction.getEndDate().compareTo(new Date())>0,"优惠券已过期，无法领取");
                coupon.setUserId(param.getUserId());
                coupon.setCouponDiscountPrice(deduction.getDeductionAmount());
                coupon.setImage(deduction.getImage());
                coupon.setCouponId(Long.valueOf(param.getCouponId()));
                coupon.setCouponType(param.getCouponType());
                coupon.setStartTime(deduction.getStartDate());
                coupon.setEndTime(deduction.getEndDate());
                coupon.setCouponContent(deduction.getCouponName());
                coupon.setCouponStatus(StatusEnum.USER_COUPON_NOT_USE.getCode());
                coupon.setCouponNum(deduction.getDeductionId());
                coupon.setBuffFlag(deduction.getBuffFlag());
                save(coupon);
                break;
            }
            //满减券
            case (2):{
                FullDiscountCoupon discountCoupon = fullDiscountCouponService.getById(param.getCouponId());
                Assert.state(discountCoupon!=null,"优惠券信息错误");
                Assert.state(discountCoupon.getEndDate().compareTo(new Date())>0,"优惠券已过期，无法领取");
                coupon.setUserId(param.getUserId());
                coupon.setImage(discountCoupon.getImage());
                coupon.setCouponDiscountPrice(discountCoupon.getDiscountAmount());
                coupon.setCouponId(Long.valueOf(param.getCouponId()));
                coupon.setCouponType(param.getCouponType());
                coupon.setStartTime(discountCoupon.getStartDate());
                coupon.setEndTime(discountCoupon.getEndDate());
                coupon.setCouponContent(discountCoupon.getCouponName());
                coupon.setCouponStatus(StatusEnum.USER_COUPON_NOT_USE.getCode());
                coupon.setCouponNum(discountCoupon.getFullDiscountCouponId());
                coupon.setBuffFlag(discountCoupon.getBuffFlag());
                save(coupon);
                break;
            }
            //服务券
            case (3):{
                ServiceCoupon serviceCoupon = serviceCouponService.getById(param.getCouponId());
                Assert.state(serviceCoupon!=null,"优惠券信息错误");
                Assert.state(serviceCoupon.getEndDate2().compareTo(new Date())>0,"优惠券已过期，无法领取");
                coupon.setUserId(param.getUserId());
                coupon.setImage(serviceCoupon.getImage());
                coupon.setCouponId(Long.valueOf(param.getCouponId()));
                coupon.setCouponType(param.getCouponType());
                coupon.setStartTime(serviceCoupon.getStartDate2());
                coupon.setEndTime(serviceCoupon.getEndDate2());
                coupon.setCouponContent(serviceCoupon.getCouponName2());
                coupon.setCouponStatus(StatusEnum.USER_COUPON_NOT_USE.getCode());
                coupon.setCouponNum(serviceCoupon.getServiceCouponId());
                coupon.setBuffFlag(serviceCoupon.getBuffFlag());
                save(coupon);
                break;
            }
            default:{
                break;
            }
        }
        return Result.success(CommonResultCodeEnum.SUCCESS,"领取成功",null);
    }

    @Scheduled(cron = "1 1 0 * * ?")
    @Override
    public void modifyCouponState() {
        List<Coupon> list = list();
        Date date = new Date();
        list.forEach(o->{
            if (o.getCouponStatus()==StatusEnum.USER_COUPON_NOT_USE.getCode()&&o.getEndTime().compareTo(date)<0)
                o.setCouponStatus(StatusEnum.USER_COUPON_LATE.getCode());
        });
        updateBatchById(list);
    }

    @Override
    public Result<Coupon> useCoupon(Long userId,Long couponId) {
        QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
        wrapper.eq("coupon_id",couponId).eq("user_id",userId);
        Coupon coupon = getOne(wrapper);
        if (coupon.getCouponStatus()==1)
            throw new MallException(CommonResultCodeEnum.ILLEGAL_STATE,"优惠券已使用或已过期");
        if (coupon==null) throw new MallException(CommonResultCodeEnum.DATA_NOT_FOUND,"还未领取该优惠券");
        if (coupon.getEndTime().compareTo(new Date())<0)
            throw new MallException(CommonResultCodeEnum.ILLEGAL_STATE,"优惠券已过期");
        coupon.setCouponStatus(StatusEnum.USER_COUPON_USED.getCode());
        updateById(coupon);
        return Result.success(coupon);
    }

    @Override
    public Result<List<ServiceCoupon>> getMyServiceCoupon(Long serviceId, Long userId) {
        List<Coupon> list = list(new QueryWrapper<Coupon>()
                .eq("user_id", userId).eq("coupon_type", StatusEnum.SERVICE_FLAG.getCode()));
        if (list==null||list.size()==0) return Result.fail("没有该类优惠券可用");
        List<String> longList = list.stream().map(o -> o.getCouponNum()).collect(Collectors.toList());
        ArrayList<ServiceCoupon> serviceCoupons1 = new ArrayList<>();
        for (String s : longList) {
            ServiceCoupon serviceCoupon = serviceCouponService.getById(s);
            if (serviceCoupon.getServiceId()==serviceId)
            serviceCoupons1.add(serviceCoupon);
        }
        return Result.success(serviceCoupons1);
    }

    @Override
    public Result<List<FullDiscountCoupon>> getMyDiscount(Long userId) {
        List<Coupon> list = list(new QueryWrapper<Coupon>()
                .eq("user_id", userId).eq("coupon_type", StatusEnum.FULL_DISCOUNT_FLAG.getCode()));
        if (list==null||list.size()==0) return Result.fail("没有该类优惠券可用");
        List<String> longList = list.stream().map(o -> o.getCouponNum()).collect(Collectors.toList());
        ArrayList<FullDiscountCoupon> serviceCoupons1 = new ArrayList<>();
        for (String s : longList) {
            FullDiscountCoupon serviceCoupon = fullDiscountCouponService.getById(s);
            serviceCoupons1.add(serviceCoupon);
        }
        return Result.success(serviceCoupons1);
    }

    @Override
    public Result<List<Deduction>> getMyCouponBySpuId(Long spuId, Long userId) {
        List<Coupon> list = list(new QueryWrapper<Coupon>()
                .eq("user_id", userId).eq("coupon_type", StatusEnum.DEDUCTION_FLAG.getCode()));
        if (list==null||list.size()==0) return Result.fail("没有该类优惠券可用");
        List<String> collect = list.stream().map(o -> o.getCouponNum()).collect(Collectors.toList());
        ArrayList<Deduction> serviceCoupons1 = new ArrayList<>();
        for (String s : collect) {
            Deduction serviceCoupon = deductionService.getById(s);
            CouponSpu couponSpu = couponSpuService.getOne(new QueryWrapper<CouponSpu>().
                    eq("coupon_id", serviceCoupon.getDeductionId()));
            if (couponSpu.getSpuId()==spuId)
            serviceCoupons1.add(serviceCoupon);
        }
        return Result.success(serviceCoupons1);
    }
}
